import mergeOptions from "./utils/merge-options";
import { isObject } from "./utils/obj";
import  * as stylesheet from './utils/stylesheet'
import * as setup from './setup';
import { use as middlewareUse, TERMINATOR } from './tech/middleware.js';
import * as browser from './utils/browser.js';
import extendFn from "./extend";

export default videojs

function videojs (id, options, ready) {
  let player = videojs.getPlayer(id)
  if (player) {
    if (options) {
      console.log('player已经被初始化,options不会起作用')
    }
    if (ready) {
      player.ready(ready)
    }
    return player
  }

  const el = getEl(id)

  if (!dom.isEl(el) || !document.body.contains(el)) {
    throw new Error('id不是一个dom')
  }

  options = options || {}

  videojs.hooks('beforesetup').forEach((hookF) => {
    const opts = hookFunction(el, mergeOptions(options))

    if (!isObject(opts) || Array.isArray(opts)) {
      console.log('beforesetup请返回一个object')
      return
    }

    options = mergeOptions(options, opts)
  })

  const PlayerComponent = Component.getComponent('Player')

  player = new PlayerComponent(el, options, ready)

  videojs.hooks('setup').forEach((hookf) => hookf(player))

  return player

}

videojs.hooks_ = {}

// 在videojs.hooks_[type]钩子函数列表里添加函数
videojs.hooks = function (type, fn) {
  videojs.hooks_[type] = videojs.hooks_[type] || []
  if (fn) {
    videojs.hooks[type] = videojs.hooks_[type].concat(fn)
  }
  return videojs.hooks_[type]
}

videojs.hook = function (type, fn) {
  videojs.hooks(type, fn)
}

// 添加只执行一次的hook 牛！！
videojs.hookOnce = function (type, fn) {
  videojs.hooks(type, [].concat(fn).map(original => {
    const wrapper = (...args) => {
      videojs.removeHook(type, wrapper)
      return original(...args)
    }
    return wrapper
  }))
}

videojs.removeHook = function (type, fn) {
  const index = videojs.hooks(type).indexOf()

  if (index <= -1) {
    return false
  }

  videojs.hooks_[type] = videojs.hooks_[type].slice()
  videojs.hooks_[type].splice(index, 1)

  return true
}


// 添加默认的styles
if (window.VIDEOJS_NO_DYNAMIC_STYLE !== true && Dom.isReal()) {
  let style = Dom.$('.vjs-styles-defaults')

  if (!style) {
    style = stylesheet.createStyleElement('vjs-styles-defaults')

    const head = Dom.$('head')
    if (head) {
      head.insertBefore(style, head.firstChild)
    }
    stylesheet.setTextContent(style, `

      .video-js {
        width: 300px;
        height: 150px;
      }

      .vjs-fluid {
        padding-top: 56.25%;
      }
    `)
  }
}

// html加载播放器的方式 <video data-setup="{}"><source></source></video>
setup.autoSetupTimeout(1, videojs)

videojs.VERSION = VERSION

videojs.options = Player.prototype._options_  // 全局的options

videojs.getPlayers = () => Player.players

videojs.getPlayer = (id) => {
  const players = Player.players
  let tag

  if (players[id]) {
    return players[id]
  }
}

// 获取所有可用的Player，不是 null
videojs.getAllPlayers = () => {
  return Object.keys(Player.players).map(k => Player.players[k]).filter(Boolean)
}

videojs.getComponent = Component.getComponent


/**
 * 注册组件，这样就能通过name获取，用于component.addChild('name') 或者 options: {children: ['name']}
 * @param {*} name1
 * @param {*} comp
 */
video.registerComponent = (name, comp) {
  if (Tech.isTech(comp)) {
    console.log('你注册的component其实是一个tech, 请用videojs.registerTech(name, text)注册')
  }
  Component.registerComponent.call(Component, name, comp)
}

// 通过name获取tech
videojs.getTech = Tech.getTech

// 注册tech, 这样就能通过name引用他, 在player的tech order中使用
video.registerTech = Tech.registerTech

// 使用中间件
videojs.use = middlewareUse

Object.defineProperty(videojs, 'middleware', {
  value: {},
  writable: false,
  enumerable: true
})

Object.defineProperty(videojs.middleware, 'TERMINATOR', {
  value: TERMINATOR,
  writable: false,
  enumerable: true
})

// 对外输出utils/browser 工具函数
videojs.browser = browser

// 是否支持touch events
videojs.TOUCH_ENABLED = browser.TOUCH_ENABLED;

// 对外输出extend工具函数
videojs.extend = extendFn

// 对外输出mergeOptions函数
videojs.mergeOptions = mergeOptions

// 对外输出bind函数
videojs.bind = Fn.bind

// 注册插件 name,plugin return f
videojs.registerPlugin = Plugin.registerPlugin

videojs.plugin = (name, plugin) => {
  console.log('方法废弃了')
  return Plugin.registerPlugin(name, plugin)
}

// 根据插件名获取插件
videojs.getPlugins = Plugin.getPlugins

// 获取一个插件的版本，如果可用的话 name | version
videojs.getPluginsVersion = Plugin.getPluginVersion

// 给所有播放器添加语言 code, data | 字典
videojs.addLanguage = function (code, data) {
  code = ('' + code) .toLowerCase()

  videojs.options.languages = mergeOptions(
    videojs.options.languages,
    {[code]: data}
  )

  return videojs.options.languages[code]
}

// 向外暴露log接口
videojs.log = log

// 创建时间进度对象
videojs.createTimeRange = videojs.createTimeRanges = createTimeRanges

// seconds -> H:MM:SS or M:SS
videojs.formatTime = formatTime

// 实现一个自定义的formatTime customeFn
videojs.setFormatTime = setFormatTime

// reset format函数
videojs.resetFormatTime = resetFormatTime

// 向外暴露parseUrl函数
videojs.parseUrl = Url.parseUrl

// 判断是否跨域
videojs.isCrossOrigin = Url.isCrossOrigin

// 向外暴露eventtarget对象
videojs.EventTarget = EventTarget

// 添加事件
videojs.on = Events.on

videojs.one = Events.one
videojs.off = Events.off
videojs.trigger = Events.trigger

// 向外暴露xhr接口
videojs.xhr = xhr

// 向外暴露TextTrack类
videojs.TextTrack = TextTrack

videojs.AudioTrack = AudioTrack
videojs.VideoTrack = VideoTrack

// 向外暴露dom操作方法
[
  'isEl',
  'isTextNode',
  'createEl',
  'hasClass',
  'addClass',
  'removeClass',
  'toggleClass',
  'setAttributes',
  'getAttributes',
  'emptyEl',
  'appendContent',
  'insertContent'
].forEach(k => {
  videojs[k] = function () {
    console.log(`这些方法已经废弃了，快去使用videojs.dom.${k}()方法来替代把`)
    return Dom[k].apply(null, arguments)
  }
})

videojs.computedStyle = computedStyle
videojs.dom = Dom

// 向外暴露url工具函数
videojs.url = Url
